
#include <BGridLayout>
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BReadWrite>
#include <BStyle>
#include <BFile>
#include <BLabel>

#include "CarverHandler.h"
#include "CarverDialog.h"

CarverDialog::CarverDialog(BWidget* parent) : BDialog(parent)
{
	this->setTitle("Carver");
	
	_carverHandler = new CarverHandler();

	BGridLayout* gridLayout = new BGridLayout();
	{
		BLabel* sizeLabel = new BLabel("size");
		_brushSizeSlider = new BSlider(0, 300);
		_brushSizeSlider->setGraph(Graph_Circle_Fill);
		_brushSizeSlider->setIconSize(12);
		_brushSizeSpinBox = new BSpinBox(0, 300);

		BLabel* intensityLabel = new BLabel("intensity");
		_brushIntensitySlider = new BRealSlider();
		_brushIntensitySlider->setGraph(Graph_Circle_Fill);
		_brushIntensitySpinBox = new BLongSpinBox();

		gridLayout->addWidget(0, 0, sizeLabel);
		gridLayout->addWidget(0, 1, _brushSizeSlider);
		gridLayout->addWidget(0, 2, _brushSizeSpinBox);
		gridLayout->addWidget(1, 0, intensityLabel);
		gridLayout->addWidget(1, 1, _brushIntensitySlider);
		gridLayout->addWidget(1, 2, _brushIntensitySpinBox);
	}

	BHBoxLayout* maskLayout = new BHBoxLayout();
	{
		BLabel* maskLabel = new BLabel("Mask");
		_maskReverseButton = new BButton("reverse");
		_maskCleanButton = new BButton("clean");

		maskLayout->addWidget(maskLabel);
		maskLayout->addWidget(_maskReverseButton);
		maskLayout->addWidget(_maskCleanButton);
	}

	_showPointsCheckBox = new BCheckBox("show points");

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(gridLayout);
	vlayout->addLayout(maskLayout);
	vlayout->addWidget(_showPointsCheckBox);

	connect(_brushSizeSlider, Signal_ValueChanged, &CarverDialog::slotBrushSizeChanged);
	connect(_brushSizeSpinBox, Signal_TextEdited, &CarverDialog::slotBrushSizeChanged);
	connect(_brushIntensitySlider, Signal_Sliding, &CarverDialog::slotBrushIntensitySliderSliding);
	connect(_brushIntensitySpinBox, Signal_EditFinished, &CarverDialog::slotBrushIntensitySpinBoxEditFinished);
	connect(_brushIntensitySpinBox, Signal_ValueChanged, &CarverDialog::slotBrushIntensityChanged);
	connect(_showPointsCheckBox, Signal_Checked, &CarverDialog::slotShowPointsChecked);

}
CarverDialog::~CarverDialog()
{

}

void CarverDialog::setTerrain(BTerrain* terrain)
{
	_carverHandler->setAsset(terrain);
}
BTerrain* CarverDialog::terrain() const
{
	return _carverHandler->asset();
}

void CarverDialog::assignItemIcon(BTreeItem* item)
{
	if (item == 0)
		return;
	if (item->asset().empty())
	{
		item->setIcon(0);
	}
	else
	{
		const BStyle* style = this->realStyle();
		item->setIcon(style->icon("circle"));
	}
	if (BTreeItem* parent = item->parent())
	{
		assignItemIcon(parent);
	}
}

void CarverDialog::slotBrushSizeChanged(BObject* object, const BValue& value)
{
	if (object == _brushSizeSlider)
	{
		int size = value;
		_carverHandler->setBrushSize(size);
		_brushSizeSpinBox->setValue(size);
	}
	if (object == _brushSizeSpinBox)
	{
		int size = value;
		_carverHandler->setBrushSize(size);
		_brushSizeSlider->setValue(size);
	}
}
void CarverDialog::slotBrushIntensitySliderSliding(BObject* object, const BValue& value)
{
	BReal intensity = value;
	_brushIntensitySpinBox->setValue((BLong)intensity);
}
void CarverDialog::slotBrushIntensitySpinBoxEditFinished(BObject* object, const BValue& value)
{
	int intensity = value;
	_brushIntensitySlider->setValue(value);
}
void CarverDialog::slotBrushIntensityChanged(BObject* object, const BValue& value)
{
	_carverHandler->setIntensity(_brushIntensitySlider->ratio());
}

void CarverDialog::slotShowPointsChecked(BObject* object, const BValue& value)
{
	bool pointsVisible = value;
	_carverHandler->setPointsVisible(pointsVisible);
}

void CarverDialog::showEvent(const BEvent& event)
{
	BDialog::showEvent(event);
	_carverHandler->setBrushSize(_brushSizeSlider->value());
	_carverHandler->setIntensity(_brushIntensitySlider->ratio());
	_carverHandler->setPointsVisible(_showPointsCheckBox->checked());
	emit("apply-handler", _carverHandler);
}
void CarverDialog::hideEvent(const BEvent& event)
{
	BDialog::hideEvent(event);
	_carverHandler->detach();
}
